package com.atguigu.dao;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
@Repository
public class SimpleBaseDaoImpl extends AbstractSimpleDao {

	/**
	 * 
	 * @param procName
	 * @param list
	 * @return
	 */
	public String execProc(String procName, List<String> list) {
		String rslt = "";
		try {
			Connection conn = this.getConnection();
			CallableStatement proc = conn.prepareCall(procName);
			for (int i = 0; i < list.size(); i++) {
				proc.setString(i + 1, list.get(i));
			}
			int out=list.size()+1;
			proc.registerOutParameter(out, Types.VARCHAR);
			proc.execute();
			String data = proc.getString(out);
			rslt = data;
		} catch (Exception e) {
			e.printStackTrace();
			rslt = e.getMessage();
		}
		return rslt;
	}

	@Override
	public <X> Page<X> pagingFind(String sql, long start, long limit,
			RowMapper<X> rowMapper) {
		return this.pagingFind(sql, start, limit, rowMapper, new Object[] {});
	}

	@Override
	public <X> Page<X> pagingFind(String sql, long start, long limit,
			RowMapper<X> rowMapper, Object obj) {
		return this.pagingFind(sql, start, limit, rowMapper,
				new Object[] { obj });
	}

	@Override
	public <X> Page<X> pagingFind(String sql, long start, long limit,
			RowMapper<X> rowMapper, Object[] obj) {
		Page<X> pi = new Page<X>();
		pi.setStartNo(start);
		pi.setPageSize((int) limit);
		pi.setTotalCount(this.pagingFindCount(sql, obj));
		pi.setResult((List<X>) this.pagingFindList(sql, start,
				pi.getPageSize(), rowMapper, obj));
		return pi;
	}

	@Override
	public <X> Page<X> pagingFind(String sql, long start, long limit,
			RowMapper<X> rowMapper, Map<String, Object> map) {
		Page<X> pi = new Page<X>();
		pi.setStartNo(start);
		pi.setPageSize((int) limit);
		pi.setTotalCount(this.pagingFindCount(sql, map));
		pi.setResult((List<X>) this.pagingFindList(sql, start,
				pi.getPageSize(), rowMapper, map));
		return pi;
	}

	@Override
	public <X> List<X> pagingFindList(String sql, long start, long limit,
			RowMapper<X> rowMapper) {
		return this.pagingFindList(sql, start, limit, rowMapper,
				new Object[] {});
	}

	@Override
	public <X> List<X> pagingFindList(String sql, long start, long limit,
			RowMapper<X> rowMapper, Object obj) {

		return this.pagingFindList(sql, start, limit, rowMapper,new Object[] { obj });
	}

	@Override
	public <X> List<X> pagingFindList(String sql, long start, long limit,RowMapper<X> rowMapper, Object[] obj) {
		String newSql = this.parseObjSql(sql).toString();
		List<Object> list = new ArrayList<Object>();
		if (obj != null) {
			for (int i = 0; i < obj.length; i++) {
				list.add(obj[i]);
			}
		}
		list.add(start + limit);
		list.add(start);

		return (List<X>) this.query(newSql, rowMapper, list.toArray());
	}

	@Override
	public <X> List<X> pagingFindList(String sql, long start, long limit,
			RowMapper<X> rowMapper, Map<String, Object> map) {
		String newSql = this.parseSql(sql).toString();
		map.put("start", start);
		map.put("limit", start + limit);

		return (List<X>) this.query(newSql, rowMapper, map);
	}

	@Override
	public long pagingFindCount(String sql) {
		return this.pagingFindCount(sql, new Object[] {});
	}

	@Override
	public long pagingFindCount(String sql, Object obj) {
		return this.pagingFindCount(sql, new Object[] { obj });
	}
	@Override
	public long pagingFindCount(String sql, Object[] obj) {
		String newSql = "select count(1) from ( " + sql + "\n ) ";
		logger.debug("new count sql =" + newSql);
		return this.queryForObject(newSql,Long.class, obj);
	}
	@Override
	public long pagingFindCount(String sql, Map<String, Object> map) {
		String newSql = "select count(1) from ( " + sql + "\n ) ";
		logger.debug("new count sql =" + newSql);
		return this.getNamedParameterJdbcTemplate().queryForObject(newSql, map,Long.class);
	}
	@Override
	public String genPkBySeqname(String seqName) {

		StringBuffer sb = new StringBuffer();
		sb.append("SELECT\n");
		sb.append("    " + seqName + ".NEXTVAL \n");
		sb.append("  FROM DUAL\n");

		String sql = sb.toString();

		long l = this.queryForObject(sql,Long.class, new Object[] {});
		return String.valueOf(l);
	}

	/**
	 * parseSql
	 * 
	 * @param sql
	 * @return 添加条件后的SQL语句
	 */
	private String parseSql(String sql) {
		// sql = sql.toLowerCase();
		StringBuffer newsql = new StringBuffer("");

		// String field = sql.substring(fieldstart, fieldend);

		newsql.append(" select * ");
		// newsql.append(field);
		newsql.append(" from (");
		newsql.append(" select pagetable.*");
		// newsql.append(field);
		newsql.append(", rownum rn  from ( ");
		newsql.append(sql);
		newsql.append(" \n) pagetable where rownum<= :limit ) where rn > :start ");

		logger.debug("new sql=" + newsql);
		return newsql.toString();
	}

	/**
	 * parseSql
	 * 
	 * @param sql
	 * @return 添加条件后的SQL语句
	 */
	private String parseObjSql(String sql) {
		// sql = sql.toLowerCase();
		StringBuffer newsql = new StringBuffer("");

		// String field = sql.substring(fieldstart, fieldend);

		newsql.append(" select * ");
		// newsql.append(field);
		newsql.append(" from (");
		newsql.append(" select pagetable.*");
		// newsql.append(field);
		newsql.append(", rownum rn  from ( ");
		newsql.append(sql);
		newsql.append(" \n) pagetable where rownum<= ? ) where rn > ? ");

		logger.debug("new sql=" + newsql);
		return newsql.toString();
	}
	
}
